package club.yuit.desktop.editor;

import club.yuit.desktop.ui.JTextPanelLinePointer;
import lombok.extern.slf4j.Slf4j;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.*;
import java.awt.*;

/**
 * @author: yuit
 * @date: 2023/12/01 1:48
 */
@Slf4j
public class EditorPanel extends JTextPane {

    private final JTextPanelLinePointer pointer;
    private StyledDocument document;
    private Element root;

    /**
     * 指示器当前行标识
     */
    private int startPointIndex = 0;

    /**
     * 要发送的数据行起始位置
     */
    private int valueIndex = 0;

    private boolean addLineAble = true;

    public EditorPanel(JTextPanelLinePointer pointer) {
        this.pointer = pointer;
        document = this.getStyledDocument();
        root = document.getDefaultRootElement();
        insertTips();
        document.addDocumentListener(new DocTxtListener());
    }

    @Override
    public void paint(Graphics g) {

        super.paint(g);

        int cl = lineCount();
        if (cl != startPointIndex) {
            int line = Math.abs(cl - startPointIndex);
            log.debug("lineCount: {}, startPointIndex: {}",cl,startPointIndex);
            if (cl < startPointIndex) {
                for (int i = 0; i < line; i++) {
                    pointer.removeCurrentGroupComponent(currentLine() );
                }
            } else {

                for (int i = 0; i < line; i++) {
                    Element element = root.getElement(startPointIndex + i);
                    AttributeSet attr = element.getAttributes();
                    EditorTextLine textLine = (EditorTextLine) attr.getAttribute("lineInfo");
                    DefaultStyledDocument doc = (DefaultStyledDocument) element.getDocument();
                    doc.getLength();
                    if (textLine!=null) {

                        Color lineColor = textLine.getLingPointerColor();
                        String lineType = textLine.getLineType();

                        if(textLine.getLingPointer().equals(JTextPanelLinePointer.SEND_POINTER_VALUE)&&!pointer.isFirstGroup()){
                            // 遇到MSG 类型，创建一个消息组
                            pointer.addGroup(lineType,  lineColor);
                        }
                        pointer.addCurrentGroupComponent(lineType,  lineColor, startPointIndex + i);

                    }
                }
            }

            startPointIndex = lineCount();
        }


    }

    @Override
    public Insets getInsets() {
        return new Insets(2, 0, 20, 0);
    }


    /**
     * 获取总行数
     *
     * @return
     */
    public int lineCount() {
        return root.getElementCount();
    }


    public void setFont(Font font) {
        super.setFont(font);
    }


    /**
     * 获取鼠标所在的行
     *
     * @return
     */
    public int currentLine() {
        int caretPosition = this.getCaretPosition();
        return root.getElementIndex(caretPosition) + 1;
    }




    public void insertValueDefaultAttr(String value) {
        insertValue(value, document.getLength(), Color.BLACK, JTextPanelLinePointer.SPLIT_POINTER_VALUE, Color.BLACK);
    }

    public void insertValueDefaultAttr(String value, Color color) {
        insertValue(value, document.getLength(), color, JTextPanelLinePointer.SPLIT_POINTER_VALUE, Color.BLACK);
    }

    public void insertValueSplitEnd(String value) {
        insertValue(value, document.getLength(), Color.GRAY, JTextPanelLinePointer.SPLIT_END_POINTER_VALUE, Color.GRAY);
    }

    public void insertValueMSG(String value) {
        insertValue(value, document.getLength(), Color.GRAY, JTextPanelLinePointer.SEND_POINTER_VALUE, Color.BLUE);

    }


    public void insertValueRES(String value) {
        insertValue(value, document.getLength(), Color.blue, JTextPanelLinePointer.STATUS_POINTER_VALUE, Color.GREEN);
    }


    /**
     * 指定位置插入值
     *
     * @param value
     * @param offset
     * @param color
     */
    public void insertValue(String value, int offset, Color color, String lineType, Color lineColor) {
        if (value != null && !value.isEmpty()) {
            SimpleAttributeSet attr = new SimpleAttributeSet();
            EditorTextLine line =  new EditorTextLine(lineType,lineType,lineColor);
            attr.addAttribute("lineInfo", line);
            StyleConstants.setForeground(attr, color);
            try {
                document.insertString(offset, value, attr);
                document.setParagraphAttributes(offset+1,value.length(),attr,false);
                log.debug("offset:{},panelLength: {},docLength: {},valueLength: {}",offset,this.getText().length(),document.getLength(),value.length());
                this.setCaretPosition(document.getLength());
            } catch (BadLocationException e) {
                throw new RuntimeException(e);
            }

        }
    }




    public void insertTips() {
        String tips = "-------------------Alt(option)+Enter 发送数据------------------\n";
        insertValueMSG(tips);
        resetStyle();
        this.valueIndex++;
       this.setCaretPosition(document.getLength());
    }


    /**
     * 获取指示器当前行到围挡末尾数据
     *
     * @return
     */
    public String getValueByIndex() {
        document.getDefaultRootElement();
        Element element = root.getElement(valueIndex);
        int startOffset = element.getStartOffset();
        try {
            return document.getText(startOffset, document.getLength() - startOffset);
        } catch (BadLocationException e) {
            throw new RuntimeException(e);
        }
    }


    public void resetStyle() {
        SimpleAttributeSet attr = new SimpleAttributeSet();
        StyleConstants.setForeground(attr, Color.RED);
        EditorTextLine line =  new EditorTextLine(JTextPanelLinePointer.SPLIT_POINTER_VALUE,JTextPanelLinePointer.SPLIT_POINTER_VALUE,Color.BLACK);
        attr.addAttribute("lineInfo", line);
        document.setParagraphAttributes(document.getLength(), document.getLength()-this.getText().length(), attr, true);
    }


    public int getValueIndex() {
        return valueIndex;
    }


    public void setValueIndex(int valueIndex) {
        this.valueIndex = valueIndex;
    }
}

class DocTxtListener implements DocumentListener {
    @Override
    public void insertUpdate(DocumentEvent e) {

    }

    @Override
    public void removeUpdate(DocumentEvent e) {
        Document document = e.getDocument();

    }

    @Override
    public void changedUpdate(DocumentEvent e) {

    }
}
